package aiku.numericalcontroloa.Service.Impl;

import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.DevicesMapper;
import aiku.numericalcontroloa.Model.Entity.Devices;
import aiku.numericalcontroloa.Model.Vo.AssembleInfoVo;
import aiku.numericalcontroloa.Model.Vo.Part;
import aiku.numericalcontroloa.Model.Vo.ProductPartVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import aiku.numericalcontroloa.Model.Entity.ProductPart;
import aiku.numericalcontroloa.Service.ProductPartService;
import aiku.numericalcontroloa.Mapper.ProductPartMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author 马
* @description 针对表【product_part】的数据库操作Service实现
* @createDate 2024-03-07 11:35:41
*/
@Service
public class ProductPartServiceImpl extends ServiceImpl<ProductPartMapper, ProductPart>
    implements ProductPartService{

    @Autowired
    private ProductPartMapper productPartMapper;
    @Autowired
    private ProductPartService productPartService;
    @Autowired
    private DevicesMapper devicesMapper;
    /**
     * 添加产品配件
     * @param partVo
     * @return
     */
    @Override
    public Result addProductPart(ProductPartVo partVo) {
        if (partVo==null){
            return Result.error(201,"参数错误");
        }
        if (partVo.getPart().size()<=0){
            return Result.error(201,"数量不能为空");
        }
        //查询产品id是否存在
        Devices devices = devicesMapper.selectById(partVo.getDevicesId());
        if (devices==null){
            return Result.error(201,"产品不存在");
        }
        //
            List<ProductPart> productPartList = new ArrayList<>();
        for (int i = 0; i < partVo.getPart().size(); i++) {
            ProductPart productPart = new ProductPart();
            productPart.setDevicesId(partVo.getDevicesId());
            productPart.setPartId(partVo.getPart().get(i).getPartId());
            productPart.setNumber(partVo.getPart().get(i).getNumber());
            productPart.setModel(partVo.getModel());
            productPartList.add(productPart);

        }
        //添加之前删除所有有关的零件，批量添加
        LambdaQueryWrapper<ProductPart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProductPart::getDevicesId, partVo.getDevicesId());
        productPartService.remove(queryWrapper);
        productPartService.saveBatch(productPartList);
        return Result.success("操作成功");
    }

    /**
     * 根据id查询产品配件
     * @param id
     * @return
     */
    @Override
    public Result selectProductPartId(String id) {
        //TODO 权限还未实现
        //查询是否有改产品
        Devices devices = devicesMapper.selectById(id);
        if (devices==null){
            return Result.error("产品不存在");
        }
        //如果有,查询配件关系表
        List<ProductPart> productPartList = productPartMapper.selectList(new LambdaQueryWrapper<ProductPart>().eq(ProductPart::getDevicesId, id));
        if (productPartList.size()<=0){
            return Result.success(new ArrayList<Part>());
        }
        //获取配件id
        List<String> partIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toList());
        //拿到配件id去仓库查询配件信息
        List<Devices> devicesList = devicesMapper.selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId, partIdList));
        Map<String, Devices> devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, Function.identity()));

        List<Part> partList = new ArrayList<>();
        for (ProductPart productPart : productPartList) {
            Part part = new Part();
            part.setPartId(productPart.getPartId());
            part.setNumber(productPart.getNumber());
            part.setPartName(devicesMap.get(productPart.getPartId()).getPartName()+productPart.getNumber()+"个");
            part.setProductPartId(productPart.getId());
            partList.add(part);
        }

        return Result.success(partList);
    }

    /**
     * 查询产品配件列表，如果差零件，则返回所差的零件信息，返回百分比 x/n*d
     * @param productPartId
     * @return
     */
    @Override
    public Result selectProductPartList(String productPartId) {
        //TODO 还未做权限
        //查询是否有该产品
        Devices devices = devicesMapper.selectById(productPartId);
        if (devices==null){
            List arrayList = new ArrayList<>();
            return Result.success(new AssembleInfoVo());
        }
        //查询该产品配置关系表
        List<ProductPart> productPartList = productPartMapper.selectList(new LambdaQueryWrapper<ProductPart>().eq(ProductPart::getDevicesId, productPartId));

        if (productPartList.size()<=0){
            return Result.success(new AssembleInfoVo());
        }
        //拿到零件id去仓库查询零件信息
        List<String> productPartIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toList());
        List<Devices> devicesList = devicesMapper.selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId, productPartIdList));
        Map<String, ProductPart> partMap = productPartList.stream().collect(Collectors.toMap(ProductPart::getPartId, Function.identity()));
        Map<String, Devices> devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, Function.identity()));

        //拿出单个产品所有零件所需数量之和,使用公式  100/sum
        Float sum = productPartList.stream().map(ProductPart::getNumber).reduce(0.0f, Float::sum);
        //倍数
        double mult = 100.0/sum;
        //总和
        Float count = 0.0f;
        for (ProductPart productPart : productPartList) {
            //现有零件小于所需零件时,加入现有零件到count中
            Float ikt = devicesMap.get(productPart.getPartId()).getCount();
            if (ikt<productPart.getNumber()){
                count = count + ikt;
            }else{
                count = count + productPart.getNumber();
            }
        }
        DecimalFormat df = new DecimalFormat("#.##");
        //查询出百分比
        double perCent = mult*count;
        String formattedMult = df.format(perCent);
        perCent = Double.parseDouble(formattedMult);
        if (perCent>99){
            perCent = 100;
        }
        //该产品能组装多少个,这是存放零件能组装多少个
        Map<String, Float> hashMap = new HashMap<>();

        for (ProductPart productPart : productPartList) {
            Devices device = devicesMap.get(productPart.getPartId());
            Float k = device.getCount()/productPart.getNumber();
            hashMap.put(productPart.getPartId(), k);
        }

        //找到最少的就是组装最多数量
        int min = Integer.MAX_VALUE;
        //零件不齐的key
        List<String> keysWithValueZero = new ArrayList<>();
        for (Map.Entry<String, Float> entry : hashMap.entrySet()) {
            if (entry.getValue() < min) {
                min = entry.getValue().intValue();
            }
            //等于0的零件
            if (entry.getValue() == 0) {
                keysWithValueZero.add(entry.getKey());
            }
        }
        //查询出缺少的零件数量和信息
        System.out.println("零件不齐的key========================================");
        System.out.println(keysWithValueZero);
        //拿到零件不齐的key,查询所需零件和现有零件数量,可以用所需零件减去现有零件,等于还差多少零件数
        List objs = new ArrayList<>();
        if (keysWithValueZero.size()>0){
            for (String keys : keysWithValueZero) {
                //所需零件
                Devices dev = new Devices();
                dev.setPartName(devicesMap.get(keys).getPartName());
                dev.setCount(partMap.get(keys).getNumber()-devicesMap.get(keys).getCount());
                objs.add(dev);
                System.out.println("所需零件=============:"+partMap.get(keys).getNumber());
                System.out.println("现有零件=============:"+devicesMap.get(keys).getCount());
                System.out.println("还差多少零件数:========================================================"+(partMap.get(keys).getNumber()-devicesMap.get(keys).getCount()));
                System.out.println(objs);
            }
        }
        System.out.println("最多能组装:========================================================"+min);
        AssembleInfoVo assembleInfoVo = new AssembleInfoVo();
        assembleInfoVo.setPartList(objs);
        assembleInfoVo.setAssemblePercent(perCent);
        assembleInfoVo.setMaxCont(min);
        return Result.success(assembleInfoVo);
    }
}




